今天將會來介紹如何實際針對文本進行文檔的切割,我會使用LangChain所提供的TextSpliter作為切割工具,最終使用pymongo去將文件儲存起來。
循環切割
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 初始化文本分割器
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=300, # 每個片段的最大字元數
chunk_overlap=70 # 每個片段之間的重疊字元數
)
# 使用分割器將長文本切割成片段
chunks = text_splitter.split_text(text)
# 定義一個函數來清除多餘的空格
def clean_text(text):
# 使用split和join來去除多餘空格
return ' '.join(text.split())
# 假設chunks是分割後的文本片段列表
clean_chunks_recursive = [clean_text(chunk) for chunk in chunks]
print(len(clean_chunks))
# 查看分割後的片段
for i, chunk in enumerate(clean_chunks_recursive):
print(f"Chunk {i+1}:\n{chunk}\n")
print("=====================================")
註:這邊額外定義了一個clean_text的function主要就是想要去清除網頁格式造成的太多空格問題
段落切割
# 初始化文本分割器
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=300, # 每個片段的最大字元數
separators=["\n\n", "\n", "。", ","," "], # 指定段落分隔符
chunk_overlap=70 # 每個片段之間的重疊字元數
)
# 使用分割器將長文本切割成片段
chunks = text_splitter.split_text(documents[0].page_content)
# 定義一個函數來清除多餘的空格
def clean_text(text):
# 使用split和join來去除多餘空格
return ' '.join(text.split())
# 假設chunks是分割後的文本片段列表
clean_chunks_sections = [clean_text(chunk) for chunk in chunks]
print(len(clean_chunks))
# 查看清理後的片段
for i, clean_chunk in enumerate(clean_chunks_sections):
print(f"Chunk {i+1}:\n{clean_chunk}\n")
print("=====================================")
註1:這邊額外定義了一個clean_text的function主要就是想要去清除網頁格式造成的太多空格問題
註2:在seperators的地方我們就指定一些常見的切換段落的字元或符號,這樣當判斷到相關的字符時就可以判斷是前後文屬於不同段落。但是這也只是高機率是屬於不同段落,還是有可能不是真正原本文章創作者的分段。
接著我們就可以將chunks儲存到MongoDB當中,
from pymongo import MongoClient
connecting_string = "your_connection_string"
client = MongoClient(connecting_string)
db = client['practice_CRUD']
collection = db['contexts'] #我們將chunks開立一個新的collection儲存
# 插入每個片段到集合中
for i, chunk in enumerate(clean_chunks_recursive):
document = {
'chunk_id': i + 1,
'content': chunk
}
collection.insert_one(document)
執行完成之後,現在到Compass上面觀看即可看到資料存入,記得要Refresh一下才可以看到資料。
現在基本上就已經快完成基本RAG的前置作業,只剩下要建立專屬Vector Search要使用的Indexes。明天我們將會完成基本的RAG前置作業,就快要可以自己實踐出一套RAG支持的聊天機器人啦~
最後來分享一下過去實習的時候就是使用Recursive方式的切割,依當時的狀況看起來這樣的切割方式其實已經可以滿足大部分的需求,像是普通的文件或文章。但是如果是一些法條的話可能就會比較不適合使用Recursive,或者可以透過另外的前置處理機制來調整一下文件結構,幫助LangChain進行文章的切割。例如需要先將文檔去做編號的辨識來確保每個法條都獨立且明顯的可被辨識。